package com.edan.partnerback.service.impl.Aspect;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.edan.partnerback.common.annotation.AutoLog;
import com.edan.partnerback.entity.Log;
import com.edan.partnerback.entity.User;
import com.edan.partnerback.service.ILogService;
import com.edan.partnerback.utils.IpUtils;
import com.edan.partnerback.utils.SessionUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @Description 功能描述
 * @Author Edan
 * @Create 2024/4/17 16:40
 */
@Component
@Slf4j
@Aspect
public class LogAspect {
    @Resource
    private ILogService logService;

    @Around("@annotation(autoLog)")
    public Object autoLog(ProceedingJoinPoint joinPoint, AutoLog autoLog) throws Throwable {
        long startTime = SystemClock.now();
        // 执行目标方法
        Object result = joinPoint.proceed();
        // 执行时间
        long time = SystemClock.now() - startTime;
        //操作
        String name = autoLog.value();
        HttpServletRequest request = getRequest();
        //获取请求url
        String url = request.getRequestURL().toString();
        if (url.contains("/file/download")) {
            return result;
        }
        // 操作人
        String username = "";
        // 判断是否登录
        try {
            StpUtil.checkLogin();
            User user = SessionUtils.getUser();
            if (user != null) {
                username = user.getUsername();
            }
        } catch (Exception e) {
            username = "游客" + RandomUtil.randomString(6);
        }
        String finalUsername = username;
        ThreadUtil.execAsync(() -> {
            // 请求参数
            String params = "";
            Object[] args = joinPoint.getArgs();
            if (args.length > 0) {
                Object arg0 = args[0];
                if (arg0 instanceof MultipartFile) {
                    params = "文件流";
                } else if (arg0 instanceof String || arg0 instanceof Long || arg0 instanceof Integer) {
                    params = arg0.toString();
                } else {
                    params = JSONUtil.toJsonStr(args[0]);
                }
            }
            // 返回数据
            String returnValue = JSONUtil.toJsonStr(result);
            if (returnValue.length() > 1000) {
                returnValue = "数据过大，返回状态码：" + JSONUtil.parseObj(returnValue).getStr("code");
            }
            // ip 和地址
            Dict ipAndCity = IpUtils.getIPAndCity();
            String ip = ipAndCity.getStr("ip");
            String city = ipAndCity.getStr("city");

            // 保存到数据库
            Log log = Log.builder().name(name).params(params).output(returnValue).url(url).ip(ip)
                    .address(city).duration((int) time).username(finalUsername).build();
            logService.save(log);
        });

        return result;
    }

    private HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
}
